Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimal implementation of backward verification for IBC relayer #709

Merged
merged 34 commits into from
Jan 28, 2021

Conversation

romac
Copy link
Member

@romac romac commented Nov 27, 2020

Close: #361

Description

This PR introduces support for backward verification, ie. verification of a block whose height is lower than the height of the highest trusted state.

Backward verification is implemented by taking a sliding window of length two between the trusted state and the target block and checking whether the last_block_id hash of the higher block matches the computed hash of the lower block.

This feature is only available if the unstable flag of the tendermint-light-client crate is enabled.
If the flag is disabled, then any attempt to verify a block whose height is lower than the highest trusted state will result in a TargetLowerThanTrustedState error.

Tests

This PR comes with two sets of tests:

  • Property-based tests which leverage testgen to synthesize chains of blocks of various length, to test both the happy path and failure cases by mutating the either the last_block_id hash or some property of a block which influences the computed hash in order to get a hash mismatch during backward verification.
  • An integration test in the kvstore-test crate which exercises the happy path against the kvstore proxy app in a running Tendermint node.

Performance

The algorithm implemented in this PR is very inefficient in case the target block is much lower than the highest trusted state.
For a trusted state at height T, and a target block at height H, it will fetch and check hashes of T - H blocks.

The specification details a strategy for minimizing the height of the trusted state the algorithm starts from.

Implementing this strategy would require some substantial changes to the LightStore API and is thus out of scope of this PR, but should be tackled in a follow-up, before this feature is stabilized (ie. available without the unstable flag).


  • Referenced an issue explaining the need for the change
  • Updated all relevant documentation in docs
  • Updated all code comments where relevant
  • Wrote tests
  • Updated CHANGELOG.md

@romac romac added the light-client Issues/features which involve the light client label Nov 27, 2020
@informalsystems informalsystems deleted a comment from codecov-io Dec 1, 2020
@informalsystems informalsystems deleted a comment from codecov-io Dec 16, 2020
@romac romac force-pushed the romac/backward-verif branch 2 times, most recently from 2f26850 to 84a43de Compare December 18, 2020 10:36
@romac romac force-pushed the romac/backward-verif branch 2 times, most recently from a4e2edb to 551ba8c Compare January 12, 2021 14:30
@romac romac force-pushed the romac/backward-verif branch 2 times, most recently from 2474ed9 to c333662 Compare January 22, 2021 11:55
@romac romac changed the title Backward verification Minimal implementation of backward verification for IBC relayer Jan 26, 2021
@informalsystems informalsystems deleted a comment from codecov-io Jan 26, 2021
@codecov-io
Copy link

Codecov Report

Merging #709 (50d2209) into master (4752a88) will increase coverage by 0.3%.
The diff coverage is 76.8%.

Impacted file tree graph

@@           Coverage Diff            @@
##           master    #709     +/-   ##
========================================
+ Coverage    53.6%   54.0%   +0.3%     
========================================
  Files         197     198      +1     
  Lines       13682   13861    +179     
  Branches     3482    3515     +33     
========================================
+ Hits         7341    7489    +148     
- Misses       5942    5971     +29     
- Partials      399     401      +2     
Impacted Files Coverage Δ
light-client/src/builder/light_client.rs 0.0% <0.0%> (ø)
light-client/src/errors.rs 7.5% <0.0%> (-0.5%) ⬇️
light-client/src/store.rs 40.6% <0.0%> (ø)
light-client/src/tests.rs 55.9% <ø> (ø)
light-client/src/utils/std_ext.rs 31.2% <0.0%> (ø)
testgen/src/light_chain.rs 86.0% <71.4%> (-7.9%) ⬇️
light-client/tests/backward.rs 79.1% <79.1%> (ø)
light-client/src/light_client.rs 68.3% <88.8%> (+11.7%) ⬆️
light-client/tests/light_client.rs 87.0% <100.0%> (+1.3%) ⬆️
light-client/tests/supervisor.rs 85.0% <100.0%> (+0.2%) ⬆️
... and 9 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4752a88...50d2209. Read the comment docs.

@romac romac marked this pull request as ready for review January 26, 2021 17:22
Copy link
Contributor

@thanethomson thanethomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a first pass here, looks awesome so far! Will take another look a little later today.

@@ -14,3 +14,6 @@ Cargo.lock

# RPC probe results
/rpc-probe/probe-results/

# Proptest regressions dumps
**/*.proptest-regressions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't we supposed to keep the regressions in version control?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question, I would have thought not since those are evidence of a test failing and would typically be fixed and thus obsolete before the PR gets merged. But perhaps I am understanding this wrong?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of proptest's failure persistence is that it re-runs any previous known failure cases before trying to generate any more novel ones, which provides additional assurance in future that the bug has been eliminated.

I haven't used proptest extensively though and may not be using it properly yet. In playing around with it today I found that it works well when you write failing tests for the first time (it persists the random seed it used to create that failure as claimed in the docs). When you then introduce a new failing test, it doesn't update the regressions file for some reason.

But if you delete the regressions folder entirely and both tests fail, it saves the seeds for both failing tests 🤷‍♂️

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I had missed that, really neat feature actually, though it seems a bit brittle indeed in some cases.

Then it makes sense to not ignore those files and leave it it up to developers to check in these regressions in or not (one may not want to check-in a regression for a broken test).

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'd say that, with property-based testing, any regressions anyone finds should be captured and committed.

Not checking it in is analogous to writing a test locally that fails on your machine (potentially showing that something's broken), but not adding it to version control, so the bug/broken code never gets found by others 😁

Copy link
Contributor

@thanethomson thanethomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks great. I think that we'll pick up any further issues on the IBC side and we can fix them as we encounter them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
light-client Issues/features which involve the light client
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement minimal support for backward verification in light client
3 participants